package com.telit.communicate.communicate;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.telit.communicate.constant.CommunicateVariable;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.net.Inet4Address;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;


/**
 * @author zhouyu
 * @description 注册客户端
 */
@Component
@Slf4j
public class RegisterServerStarter {

    @Autowired
    private ZookeeperRegister zookeeperRegister;

    @Value("${zookeeper.protocol}")
    private String protocol;

    @Value("${server.port}")
    private int port;

    @Value("${server.servlet.context-path}")
    private String path;

    private ExecutorService executorService;


    /**
     * 创建线程池来单独注册到服务端
     */
    @PostConstruct
    public void setup() {
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                .setNameFormat("RegisterStarter-Thread-%d").build();
        executorService = Executors.newSingleThreadExecutor(namedThreadFactory);
        doRegister();
    }


    /**
     * 注册到服务端
     */
    public void doRegister() {
        executorService.execute(() -> {
                    while (!CommunicateVariable.registerSuccess.get()) {
                        try {
                            ZooKeeper zooKeeper = zookeeperRegister.getZooKeeper();
                            if (zooKeeper==null){
                                break;
                            }
                            //注册服务端
                            String hostAddress = Inet4Address.getLocalHost().getHostAddress();
                            String serverName = "/" + hostAddress + ":" + port;
                            if (zookeeperRegister.exists(serverName)) {
                                break;
                            }
                            zooKeeper.create(serverName, (protocol + hostAddress + ":" + port + path + "/msg/send").getBytes(), ZooDefs.Ids.READ_ACL_UNSAFE, CreateMode.EPHEMERAL);
                            log.info("create node to zookeeper success!!!");
                            CommunicateVariable.registerSuccess.compareAndSet(false, true);
                        } catch (Exception e) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException interruptedException) {
                                interruptedException.printStackTrace();
                            }
                            //注册失败继续重连
                            log.info("retry create node to zookeeper...");
                        }
                    }
                }
        );
    }
}
